package com.dhcc.bpm.modules.gateway.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.enums.ConfigType;
import com.dhcc.bpm.common.json.JSONObject;
import com.dhcc.bpm.common.redisMessage.RedisMessageSender;
import com.dhcc.bpm.modules.api.entity.Backservice;
import com.dhcc.bpm.modules.api.entity.Externalcall;
import com.dhcc.bpm.modules.api.service.IBackserviceService;
import com.dhcc.bpm.modules.api.service.IExternalcallService;
import com.dhcc.bpm.modules.gateway.entity.Authcenter;
import com.dhcc.bpm.modules.gateway.entity.GatewayRoute;
import com.dhcc.bpm.modules.gateway.service.IAuthcenterService;
import com.dhcc.bpm.modules.gateway.service.IGatewayRouteService;
import com.dhcc.bpm.modules.gateway.service.IGatewayService;
import com.dhcc.bpm.modules.gateway.vo.AuthcenterVO;
import com.dhcc.bpm.modules.system.service.ISerialNumberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * @ClassName AuthcenterController
 * @Description 授权中心表 控制器
 * @Author YaoZC
 * @Date 2020/01/19 15:32
 * @Version 1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 */
@RestController
@AllArgsConstructor
@RequestMapping("bpm-gateway/authcenter")
@Api(value = "授权中心表", tags = "授权中心表接口")
public class AuthcenterController extends BladeController {
	private static final Logger log = LoggerFactory.getLogger(AuthcenterController.class);
	private IAuthcenterService authcenterService;

	private ISerialNumberService serialNumberService;

	private IBackserviceService backService;

	private IGatewayService gatewayService;

	private IExternalcallService externalcallService;

	private IGatewayRouteService gatewayRouteService;
	@Autowired
	private RedisMessageSender redisMessageSender;
	/**
	 * @Description 查看授权中心详情
	 * @Date 2020/01/19 15:32
	 * @param authcenter
	 * @return org.springblade.core.tool.api.R<com.dhcc.bpm.modules.gateway.entity.Authcenter>
	 **/
	@ApiLog("查看授权中心详情")
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "查看授权中心详情", notes = "传入authcenter")
	@Log(title = "查看授权中心详情",businessType = BusinessType.SELECT)
	public R<Authcenter> detail(Authcenter authcenter) {
		Authcenter detail = authcenterService.getOne(Condition.getQueryWrapper(authcenter));
		return R.data(detail);
	}

	/**
	 * @Description 查看授权中心分页列表
	 * @Date 2020/01/19 15:32
	 * @param authcenter
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.gateway.entity.Authcenter>>
	 **/
	@ApiLog("查看授权中心分页列表")
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入authcenter")
	@Log(title = "查看授权中心分页列表",businessType = BusinessType.SELECT)
	public R<IPage<Authcenter>> list(@ApiIgnore @RequestParam Map<String, Object> authcenter, Query query) {
		IPage<Authcenter> pages = authcenterService.page(Condition.getPage(query), Condition.getQueryWrapper(authcenter,Authcenter.class));
		return R.data(pages);
	}

	/**
	 * @Description 查看授权中心自定义分页列表
	 * @Date 2020/01/19 15:32
	 * @param authcenter
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.gateway.vo.AuthcenterVO>>
	 **/
	@ApiLog("查看授权中心分页列表")
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入authcenter")
	@Log(title = "查看授权中心自定义分页列表",businessType = BusinessType.SELECT)
	public R<IPage<AuthcenterVO>> page(AuthcenterVO authcenter, Query query) {
		IPage<AuthcenterVO> pages = authcenterService.selectAuthcenterPage(Condition.getPage(query), authcenter);
		return R.data(pages);
	}

	/**
	 * @Description 新增授权中心记录
	 * @Date 2020/01/19 15:32
	 * @param authcenter
	 * @return org.springblade.core.tool.api.R
	 **/
	@ApiLog("新增授权中心记录")
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入authcenter")
	@Log(title = "新增授权中心记录",businessType = BusinessType.INSERT)
	public R save(@Valid @RequestBody Authcenter authcenter) {
		return R.status(authcenterService.save(authcenter));
	}

	/**
	 * @Description 修改授权中心记录
	 * @Date 2020/01/19 15:32
	 * @param authcenter
	 * @return org.springblade.core.tool.api.R
	 **/
	@ApiLog("修改授权中心记录")
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入authcenter")
	@Log(title = "修改授权中心记录",businessType = BusinessType.UPDATE)
	public R update(@Valid @RequestBody Authcenter authcenter) {
		return R.status(authcenterService.updateById(authcenter));
	}

	/**
	 * @Description 新增或修改授权中心记录
	 * @Date 2020/01/19 15:32
	 * @param authcenter
	 * @return org.springblade.core.tool.api.R
	 **/
	@ApiLog("新增或修改授权中心记录")
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入authcenter")
	@Log(title = "新增或修改授权中心记录",businessType = BusinessType.UPDATE)
	@Transactional(rollbackFor = Exception.class)
	public R submit(@Valid @RequestBody Authcenter authcenter) {
		boolean bool = false;
		Authcenter auth = null;
		if(authcenter.getId() !=null && authcenter.getId() != -1){
			auth = authcenterService.getById(authcenter.getId());
		}

		Backservice backservice = null;
		//新增后端服务
		if(auth != null && auth.getBackserviceId() != null){
			backservice = backService.getById(auth.getBackserviceId());
		}
		if (backservice == null){
			backservice = new Backservice();
			String code = serialNumberService.generateSerialNumberByModelCode("opc_backservice");
			//安全认证类型
			backservice.setSafeType(0L);
			//服务类型 (SpringCloud,dubbo,Soap等)
//			backservice.setBackserviceType(1L);
			//编号
			backservice.setBackserviceCode(code);
		}
		//授权中心名称
		backservice.setBackserviceName(authcenter.getAuthcenterName());
		//授权中心英文名称
		backservice.setBackserviceEname(authcenter.getAuthcenterEname());
		//内部服务名
		backservice.setApplicationName(authcenter.getAuthServerName());
		//是否为内部服务
		backservice.setApplyType(authcenter.getIsInside());
		//描述
		backservice.setDescribe(authcenter.getDescribe());
		//是否为权限中心
		backservice.setIsAuth(1);
		bool = backService.saveOrUpdate(backservice);
		if(authcenter.getIsInside().equals("2")){
			//后端服务外部服务
			Externalcall ec = new Externalcall();
			ec.setBackserviceId(backservice.getId());
			String url = authcenter.getAuthcenterUri().replace("http://", "");
			//ip
			ec.setIp(url.split(":")[0]);
			//端口号
			ec.setPort(Long.valueOf(url.split(":")[1]));
			externalcallService.saveOrUpdate(ec);
		}
		String routeList = null;
		if (bool) {
			//新增权限中心路由
			String[] ids = authcenter.getGateway().split(",");
			if (auth != null && auth.getRouteId() != null){
				String[] routes = auth.getRouteId().split(",");
				//先删除路由，在添加路由
				for (String route: routes){
					gatewayRouteService.removeById(route);
				}
			}
			for(int i = 0; i < ids.length ; i++) {
				try {
					GatewayRoute gatewayRoute = new GatewayRoute();
					gatewayRoute.setStatus(0);
					gatewayRoute.setBackServiceId(backservice.getId().toString());
					//网关ID
					gatewayRoute.setOpcGatewayId(Long.valueOf(ids[i]));
					String env = gatewayService.getById(gatewayRoute.getOpcGatewayId()).getEnv();
					//环境类型
					gatewayRoute.setEnv(env);
					String filter = "[{\"predicateValue\":\"" + authcenter.getPrefUrl() + "\",\"name\":\"Path\"}]";
					gatewayRoute.setRouteConfig(filter);
//						gatewayRoute.setFilters("[{\"filterValue\":\"2\",\"name\":\"StripPrefix\"}]");
					bool = gatewayRouteService.saveOrUpdate(gatewayRoute);
					if(routeList == null){
						routeList = gatewayRoute.getId().toString();
					}else {
						routeList = routeList + "," + gatewayRoute.getId();
					}

				} catch (Exception e) {
					log.info("路由入库异常：{}", e);
					bool = false;
				}
			}
		}

		if (bool){
			//权限中心入库

			//是否刷新
			authcenter.setIsRefresh(1);
			//后端服务
			authcenter.setBackserviceId(backservice.getId());
			//网关路由
			authcenter.setRouteId(routeList);
			bool = authcenterService.saveOrUpdate(authcenter);
			//刷新网关路由配置
			String message = redisMessageSender.format(ConfigType.ROUTE.name(), "刷新路由配置信息");
			redisMessageSender.sendMessageToGateway(null, message);
		}else{
			//新增路由失败，删除后端服务
			backService.removeById(backservice.getId());
		}

		if (!bool){
			//权限中心入库失败，删除后端服务和路由信息
			backService.removeById(backservice.getId());
			if(routeList != null){
				String[] ids = routeList.split(",");
				for (String id : ids){
					gatewayRouteService.removeById(id);
				}
			}
		}

		return R.status(bool);
	}


	/**
	 * @Description 删除授权中心记录
	 * @Date 2020/01/19 15:32
	 * @param ids
	 * @return org.springblade.core.tool.api.R
	 **/
	@ApiLog("删除授权中心记录")
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	@Log(title = "删除授权中心记录",businessType = BusinessType.DELETE)
	@Transactional(rollbackFor = Exception.class)
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		List<Long> list = Func.toLongList(ids);
		for (Long id: list ) {
			Authcenter auth = authcenterService.getById(id);
			if (auth.getBackserviceId() != null){
				backService.removeById(auth.getBackserviceId());
			}
			if (auth.getGateway() != null){
				String[]  routes = auth.getGateway().split(",");
				for (String route : routes){
					gatewayRouteService.removeById(Long.valueOf(route));
				}
			}
		}
		return R.status(authcenterService.deleteLogic(Func.toLongList(ids)));
	}

	/**
	 * @Description 系统服务名关联查询
	 * @Date 2020/01/19 15:32
	 * @param
	 * @return com.dhcc.bpm.common.json.JSONObject
	 **/
	@ApiLog("系统服务名关联查询")
	@GetMapping("/selectAuthCenterName")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "查询所有权限中心名称", notes = "无参")
	@Log(title = "系统服务名关联查询",businessType = BusinessType.SELECT)
	public JSONObject selectBySysName() {
		JSONObject object = new JSONObject();
		object.put("success",true);
		object.put("names", authcenterService.selectAuthCenterName());
		return object;
	}

	@ApiLog("刷新权限中心")
	@PostMapping("/refreshAuthCenter")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "刷新权限中心", notes = "无参")
	@Log(title = "刷新权限中心",businessType = BusinessType.REFRESH)
	public R refreshAuthCenter(){
		try {
			//刷新网关路由配置
			String message = redisMessageSender.format(ConfigType.ROUTE.name(), "刷新路由配置信息");
			redisMessageSender.sendMessageToGateway(null, message);
			if(authcenterService.updateAuthCenter() > 0){
				R.status(true);
			}else{
				R.status(false);
			}
		}catch (Exception e){
			log.error("刷新网关路由配置异常：{}", e);
			return R.status(false);
		}
		return R.status(true);
	}

}
